<template>
  <div style="width: 100%; height: 100%">
    <div
      class="container"
      :style="finalStyle"
      @mouseenter="onMouseEnter"
      @mouseleave="onMouseLeave"
      ref="containerRef"
    >
      <canvas ref="canvasRef">
         
      </canvas>
      <div
        class="content"
        :style="{
          left: `${leftTopHeight * 2}px`,
          right: `${leftTopHeight}px`,
          top: title
            ? `${
                leftTopHeight +
                Number.parseInt(finalStyle.fontSize) +
                titleMarginTop +
                titleMarginBottom
              }px`
            : `${leftTopHeight + titleMarginTop}px`,
          bottom: `${leftTopHeight}px`,
        }"
      >
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Border1',
  props: {
    title: {
      type: String,
      default: ''
    },
    lineWidth: {
      type: Number,
      default: 1
    },
    lineColor: {
      type: String,
      default: '#005A5A'
    },
    highlightColor: {
      type: String,
      default: '#41B1B4'
    },
    containerStyle: {
      type: Object,
      default: () => ({})
    }
  },

  data() {
    return {
      leftTopHeight: 8,
      leftToplineWidth: 8,
      leftToplineMargin: 4,
      titleMarginTop: 6,
      titleMarginBottom: 20,
      bgItemWidth: 10,
      bgColor1: '#3D5454',
      bgColor2: '#445A5A',
      arrowWidth: 10,
      arrowLineWidth: 4,
      arrowMargin: 6,
      arrowMarginTitle: 16,
      defaultStyle: {
        fontSize: '18px',
        color: '#74CCD1',
        fontWeight: 600
      },
      ctx: null,
      isHover: false,
      containerRef: null,
      canvasRef: null,
      finalStyle: {}
    }
  },

  created() {
    this.finalStyle = { ...this.defaultStyle, ...this.containerStyle }
  },

  mounted() {
    this.init()
  },

  methods: {
    drawBorderPath(drawLineWidth) {
      if (this.canvasRef && this.ctx) {
        const { width, height } = this.canvasRef
        let x = 1
        this.ctx.beginPath()
        this.ctx.moveTo(x, this.leftTopHeight)
        x = this.leftTopHeight
        this.ctx.lineTo(x, 1)
        x += 4 * this.leftToplineMargin + 3 * this.leftToplineWidth
        this.ctx.lineTo(x, 1)
        x += this.leftTopHeight
        this.ctx.lineTo(x, this.leftTopHeight)
        x = width - 2 * this.leftTopHeight
        this.ctx.lineTo(x, this.leftTopHeight)
        x = width - drawLineWidth
        this.ctx.lineTo(x, 3 * this.leftTopHeight)
        this.ctx.lineTo(x, height - drawLineWidth)
        x = 2 * this.leftTopHeight
        this.ctx.lineTo(x, height - drawLineWidth)
        x = 1
        this.ctx.lineTo(x, height - 2 * this.leftTopHeight)
        this.ctx.lineTo(x, this.leftTopHeight)
        this.ctx.closePath()
        this.ctx.lineWidth = drawLineWidth
      }
    },

    draw() {
      if (this.canvasRef && this.ctx) {
        const { width, height } = this.canvasRef
        this.ctx.clearRect(0, 0, width, height)
        this.ctx.globalCompositeOperation = "source-over"
        let drawLineWidth = this.lineWidth

        // hover时绘制背景图案
        if (this.isHover) {
          // 线加粗
          drawLineWidth += 1
          this.drawBorderPath(drawLineWidth)
          this.ctx.fillStyle = this.isHover ? this.highlightColor : this.lineColor
          this.ctx.fill()
          this.ctx.globalCompositeOperation = "source-atop"
          let x = 0
          let y = 0
          while (y <= height && x <= width) {
            const nextX = x + this.bgItemWidth
            const indexX = Math.floor(x / this.bgItemWidth)
            const indexY = Math.floor(y / this.bgItemWidth)

            if (
              (indexX % 2 === 0 && indexY % 2 === 0) ||
              (indexX % 2 !== 0 && indexY % 2 !== 0)
            ) {
              this.ctx.fillStyle = this.bgColor1
            } else {
              this.ctx.fillStyle = this.bgColor2
            }
            if (nextX > width) {
              this.ctx.fillRect(x, y, width - x, this.bgItemWidth)
              y += this.bgItemWidth
              x = 0
            } else {
              this.ctx.fillRect(x, y, this.bgItemWidth, this.bgItemWidth)
              x += this.bgItemWidth
            }
          }
        }

        this.ctx.globalCompositeOperation = "source-over"
        // 画边框
        this.drawBorderPath(drawLineWidth)
        let x = 1
        this.ctx.strokeStyle = this.isHover ? this.highlightColor : this.lineColor
        this.ctx.stroke()
        // 修改画笔粗细和颜色
        this.ctx.lineWidth = drawLineWidth + 1
        this.ctx.strokeStyle = this.highlightColor
        // 画左上角三个横线
        this.ctx.beginPath()
        x = this.leftTopHeight + this.leftToplineMargin
        this.ctx.moveTo(x, this.leftTopHeight)
        x += this.leftToplineWidth
        this.ctx.lineTo(x, this.leftTopHeight)
        this.ctx.closePath()
        this.ctx.stroke()

        this.ctx.beginPath()
        x += this.leftToplineMargin
        this.ctx.moveTo(x, this.leftTopHeight)
        x += this.leftToplineWidth
        this.ctx.lineTo(x, this.leftTopHeight)
        this.ctx.closePath()
        this.ctx.stroke()

        this.ctx.beginPath()
        x += this.leftToplineMargin
        this.ctx.moveTo(x, this.leftTopHeight)
        x += this.leftToplineWidth
        this.ctx.lineTo(x, this.leftTopHeight)
        this.ctx.closePath()
        this.ctx.stroke()
        // 画右下角直角
        this.ctx.beginPath()
        x = width - drawLineWidth
        this.ctx.moveTo(x, height - 2 * this.leftTopHeight)
        this.ctx.lineTo(x, height)
        this.ctx.closePath()
        this.ctx.stroke()
        this.ctx.beginPath()
        this.ctx.moveTo(x, height - drawLineWidth)
        x -= 2 * this.leftTopHeight
        this.ctx.lineTo(x, height - drawLineWidth)
        this.ctx.closePath()
        this.ctx.stroke()

        if (this.title) {
          // 绘制标题
          const titleWidth = 12
          this.ctx.font = `${this.finalStyle.fontWeight} ${this.finalStyle.fontSize} SourceHanSansCN-Bold`
          this.ctx.fillStyle = this.finalStyle.color
          this.ctx.fillText(
            this.title,
            (width - titleWidth) / 2,
            this.leftTopHeight + this.titleMarginTop + Number.parseInt(this.finalStyle.fontSize)
          )
          let x =
            (width - titleWidth) / 2 -
            (this.arrowMarginTitle + 2 * this.arrowWidth + this.arrowMargin)
          const y =
            this.leftTopHeight +
            this.titleMarginTop +
            Number.parseInt(this.finalStyle.fontSize) / 2 +
            2
          // 绘制标题左边箭头图案
          this.ctx.lineWidth = this.arrowLineWidth
          this.ctx.lineJoin = "miter"
          this.ctx.beginPath()
          this.ctx.moveTo(x, this.leftTopHeight + this.titleMarginTop + 4)
          this.ctx.lineTo(x + this.arrowWidth, y)
          this.ctx.lineTo(
            x,
            this.leftTopHeight + this.titleMarginTop + Number.parseInt(this.finalStyle.fontSize)
          )
          this.ctx.strokeStyle = this.isHover ? this.finalStyle.color : this.lineColor
          this.ctx.stroke()
          this.ctx.beginPath()
          this.ctx.moveTo(
            x + this.arrowWidth + this.arrowMargin,
            this.leftTopHeight + this.titleMarginTop + 4
          )
          this.ctx.lineTo(x + 2 * this.arrowWidth + this.arrowMargin, y)
          this.ctx.lineTo(
            x + this.arrowWidth + this.arrowMargin,
            this.leftTopHeight + this.titleMarginTop + Number.parseInt(this.finalStyle.fontSize)
          )
          this.ctx.strokeStyle = this.finalStyle.color
          this.ctx.stroke()
          // 绘制标题右边箭头图案
          x = (width + titleWidth) / 2 + this.arrowMarginTitle
          this.ctx.beginPath()
          this.ctx.moveTo(x + this.arrowWidth, this.leftTopHeight + this.titleMarginTop + 4)
          this.ctx.lineTo(
            x,
            this.leftTopHeight +
              this.titleMarginTop +
              Number.parseInt(this.finalStyle.fontSize) / 2 +
              2
          )
          this.ctx.lineTo(
            x + this.arrowWidth,
            this.leftTopHeight + this.titleMarginTop + Number.parseInt(this.finalStyle.fontSize)
          )
          this.ctx.strokeStyle = this.finalStyle.color
          this.ctx.stroke()
          this.ctx.beginPath()
          this.ctx.moveTo(
            x + 2 * this.arrowWidth + this.arrowMargin,
            this.leftTopHeight + this.titleMarginTop + 4
          )
          this.ctx.lineTo(
            x + this.arrowWidth + this.arrowMargin,
            this.leftTopHeight +
              this.titleMarginTop +
              Number.parseInt(this.finalStyle.fontSize) / 2 +
              2
          )
          this.ctx.lineTo(
            x + 2 * this.arrowWidth + this.arrowMargin,
            this.leftTopHeight + this.titleMarginTop + Number.parseInt(this.finalStyle.fontSize)
          )
          this.ctx.strokeStyle = this.isHover ? this.finalStyle.color : this.lineColor
          this.ctx.stroke()
        }
      }
    },

    init() {
      this.containerRef = this.$refs.containerRef
      this.canvasRef = this.$refs.canvasRef
      if (this.containerRef && this.canvasRef) {
        const { clientWidth, clientHeight } = this.containerRef
        this.canvasRef.width = clientWidth
        this.canvasRef.height = clientHeight
        this.ctx = this.canvasRef.getContext("2d")
        this.draw()
      }
    },

    onMouseEnter() {
      this.isHover = true
      this.draw()
    },

    onMouseLeave() {
      this.isHover = false
      this.draw()
    }
  }
}
</script>

<style scoped lang="scss">
.container {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  background-color: translate;
  position: relative;
  .content {
    position: absolute;
    z-index: 1;
  }
}
</style>
